// 封装axios的请求，返回重新封装的数据格式
// 对错误的统一处理
import { HttpResponse } from '@/common/interface'
import Taro from '@tarojs/taro'
import publicConfig from '@/config/index'
import { useStore } from '@/stores'
import { openIdLogin } from '@/services/apis/user'
import axios, {
  AxiosInstance,
  AxiosRequestConfig,
  AxiosResponse,
  Canceler
} from 'axios-miniprogram'
import errorHandle from '../common/errorHandle'
const auth = useStore('auth')
const CancelToken = axios.CancelToken
var isLogin = true;

const codeToLogin = () => {
  isLogin = false

  const openid = Taro.getStorageSync('openid')
  console.log(openid)
  if (openid) {
    wx.showToast({
      title: '登录过期正在自动重新登录！',
      icon: 'none',
      duration: 2000
    })
    wx.login().then(data => {
      openIdLogin(data.code).then(data => {
        Taro.setStorageSync('openid', data.openid)
        if (data.token) {
          Taro.setStorageSync('token', data.token)
          auth.setUserInfo({
            nickName: data.userName,
            avatarUrl: 'https://fmzk.harvest-code.com/api' + data.avatarUrl
          })
          auth.login()
          isLogin = true
          Taro.reLaunch({ url: `/pages/create/index` })
        }else{
          Taro.reLaunch({ url: `/pagesSub/login/index` })
        }
      })
    })
  } else {
    auth.logout()
    Taro.navigateTo({ url: `/pagesSub/login/index` })
  }

}
class HttpRequest {
  private baseUrl: string
  private pending: Record<string, Canceler>

  constructor(baseUrl: string) {
    this.baseUrl = baseUrl
    this.pending = {}
  }

  // 获取axios配置
  getInsideConfig() {
    const config = {
      baseURL: this.baseUrl,
      headers: {
        'Content-Type': 'application/json;charset=utf-8'
      },
      timeout: 10000
    }
    return config
  }

  removePending(key: string, isRequest = false) {
    if (this.pending[key] && isRequest) {
      this.pending[key]('取消重复请求')
    }
    delete this.pending[key]
  }

  // 设定拦截器
  interceptors(instance: AxiosInstance) {
    wx.showToast({
      title: '数据加载中！',
      icon: 'loading'
    })
    instance.interceptors.request.use(
      config => {
        let isPublic = false
        publicConfig.publicPath.map(path => {
          isPublic = isPublic || path.test(config.url || '')
        })
        const token = Taro.getStorageSync('token')

        if (config.method == "get") {
          config.headers['Content-Type'] = "application/x-www-form-urlencoded;charset:utf-8"
        }
        if (!isPublic && token) {
          config.headers['x-token'] = token
        }
        const key = config.url + '&' + config.method
        this.removePending(key, true)
        config.cancelToken = new CancelToken(c => {
          this.pending[key] = c
        })
        return config
      },
      err => {
        wx.hideToast();
        errorHandle(err)
        return Promise.reject(err)
      
      }
    )

    // 响应请求的拦截器
    instance.interceptors.response.use(
      res => {
   
        const key = res.config.url + '&' + res.config.method
        this.removePending(key)
       
        if (res.status === 200) {
          if (res.data.result == "false" && res.data.message == "登录超时！") {
            if (isLogin) {
              codeToLogin()
            }
          }
          wx.hideToast()
          return Promise.resolve(res.data)
        } else {
          wx.hideToast()
          return Promise.reject(res)
        }
      },
      err => {
        wx.hideToast()
        errorHandle(err)
        return Promise.reject(err)
      }
    )
  }

  // 创建实例
  request(options: AxiosRequestConfig) {
    const instance = axios.create()
    const newOptions = Object.assign(this.getInsideConfig(), options)
    this.interceptors(instance)
    return instance(newOptions)
  }

  get(url: string, config?: AxiosRequestConfig): Promise<AxiosResponse> | Promise<HttpResponse> {
    const options = Object.assign(
      {
        method: 'get',
        url: url
      },
      config
    )
    return this.request(options)
  }

  post(url: string, data?: unknown): Promise<AxiosResponse> | Promise<HttpResponse> {
    return this.request({
      method: 'post',
      url: url,
      data: data
    })
  }
}

export default HttpRequest
